package aiproject3.models;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;
import java.util.Map.Entry;
/**
 * 
 * @author Ricardo Madera
 *
 */
public class NGramModel extends Model<String,Gram> {


	/**
	 * The highest ranked character in this model (in terms of frequency)
	 */
	private String _currentPrediction;
	Vector<Character> charVector;
	Vector<Character> charHistory;
	private int nGrams;
	private NGramModel() {
		super();
		_currentPrediction = null;
		 charVector = new Vector<Character>();
		charHistory = new Vector<Character>();
	}
	/**
	 * Creats an N-Gram model based on the
	 * @param n
	 * @param trainingFile
	 * @return
	 */
	public  NGramModel createNGramModel(int n,String trainingFile) {	
		if(n<1)
		{
			System.out.println("Error: Attempted "+n+" grams but the minimum is 2");
			return null;
		}
		
		nGrams = n;
		try {
			File file = new File(trainingFile);
			if (!file.exists()) {
				System.out.println("Error: Unable to train model... Training file not found.");
			} else {
				NGramModel model = new NGramModel();
				
				FileInputStream fstream = new FileInputStream(file);
			    DataInputStream in = new DataInputStream(fstream);
			    BufferedReader br = new BufferedReader(new InputStreamReader(in));
			    Vector<Character> charVector = new Vector<Character>();
			    String strLine;
			    
			    
			    while ((strLine = br.readLine()) != null) {
		    		// Break up input-string into 'array' of elements
		    		String[] row = strLine.split("\\s*,\\s*");
		    		for (String unit : row) {
		    			if (unit.length() != 1) {
		    				System.out.println("Error: Malformed input in training file... Expecting a single character.");
		    				return null;
		    			} else
		    			{
		    				charVector.add(unit.charAt(0));
		    				
		    			}
		    		}
			    }
			    in.close();
			    
			    model = addToModel(n,model);
			    return model;
			}
		} catch (IOException ex) {
			System.out.println("Error: Unable to access training file... \n" + ex.getMessage());
		}
		return null;
	}
	/**
	 * Adds the contents of the Global character vector to the model 
	 * according to n-size grams.
	 */
	public NGramModel addToModel(int n, NGramModel model)
	{	
		int i,j;
		String tempSequence= "";
		for(i = 0; i < charVector.size(); i++)
		{
			
			for(j = 0; (j < n-1) && (i+j < charVector.size()); j++)
			{
				
				tempSequence+=charVector.get(i+j);
				
			}
			if(model._data.containsKey(tempSequence))
			{
				Gram tempGram;
				tempGram = model._data.get(tempSequence);
				tempGram.addChild(charVector.get(i+j+1));
				tempGram.addCount();
				model._data.put(tempSequence,tempGram);
			}
			else
			{
				Gram newGram = new Gram();
				newGram.addChild(charVector.get(i+j+1));
				model._data.put(tempSequence, newGram);
			}
				
		}
		
		return model;
	}

	//TODO Finish this
//	@Override
	public  String predictNext(Character currChar,NGramModel model) {
	  return null;
	}
	@Override
	public void addToModel(String unit) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public String predictNext() {
		// TODO Auto-generated method stub
		return null;
	}	
	
}
